package jnpf.database.datatype.model;

import jnpf.database.datatype.db.interfaces.DtInterface;
import jnpf.database.datatype.sync.util.DtSyncUtil;
import jnpf.database.datatype.utils.DataTypeUtil;
import jnpf.database.datatype.viewshow.ViewDataTypeEnum;
import jnpf.database.source.DbBase;
import jnpf.util.StringUtil;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Optional;

/**
 * 前端数据类型模型
 *
 * @author JNPF开发平台组 YanYu
 * @version V3.2.0
 * @copyright 引迈信息技术有限公司
 * @date 2021/10/25
 */
@Data
@NoArgsConstructor
public class ViewDtModel {

    /**
     * 前端设置数据类型
     */
    private String viewDataType;

    /**
     * 前端设置数据长度
     */
    private String viewLength;

    /**
     * 前端设置字符长度
     */
    private Long viewCharLength;

    /**
     * 前端设置精度
     */
    private Integer viewNumPrecision;

    /**
     * 前端设置标度
     */
    private Integer viewNumScale;

    /**
     * 数据类型枚举
     */
    private DtInterface dtEnum;

    /**
     * 是否打开默认精度
     */
    private Boolean isFixed = false;

    /**
     * 是否是数据库类型
     */
    private Boolean isDbDataType = false;

    /**
     * 初始化创建表使用
     * @param viewDataType 前端数据类型
     * @param viewLength 长度
     * @param dbEncode 数据库类型
     */
    public ViewDtModel(String viewDataType, String viewLength, String dbEncode) {
        this.viewDataType = viewDataType;
        this.viewLength = viewLength;
        // 设置长度
        if (viewLength == null){
            viewLength = "-1";
        }
        if(viewLength.contains(",")) {
            String[] split = viewLength.split(",");
            if(DataTypeUtil.numFlag(split[0], split[1])){
                this.viewCharLength = Long.parseLong(split[0]);
                this.viewNumPrecision = Integer.parseInt(split[0]);
                this.viewNumScale = Integer.parseInt(split[1]);
            }
        }else {
            if(DataTypeUtil.numFlag(viewLength)){
                this.viewCharLength = Long.parseLong(viewLength);
                this.viewNumPrecision = Integer.parseInt(viewLength);
            }
        }
        this.dtEnum =
            // 根据前端信息判断内置数据标准类型枚举
            Optional.ofNullable(DtInterface.newInstanceByView(viewDataType, dbEncode)).orElseGet(()->
                // 直接使用前端数据类型作为数据库类型查询
                Optional.ofNullable(DtInterface.newInstanceByDt(viewDataType, dbEncode)).orElseGet(()->{
                    try {
                        // 尝试Mysql里面寻找这个数据类型, 转成原有数据库数据类型
                        return DtSyncUtil.getToFixCovert(Optional.ofNullable(DtInterface.newInstanceByDt(viewDataType, DbBase.MYSQL)).orElseThrow(Exception::new), dbEncode);
                    } catch (Exception e) {
                        return null;
                    }
                })
        );
    }

    /**
     * 初始化显示表使用
     * @param viewCharLength 字符串长度
     * @param viewNumPrecision 精度
     * @param viewNumScale 标度
     */
    public ViewDtModel (Long viewCharLength, Integer viewNumPrecision, Integer viewNumScale){
        this.viewCharLength = viewCharLength;
        this.viewNumPrecision = viewNumPrecision;
        this.viewNumScale = viewNumScale;
    }

    /**
     * jdbc查询出对应数据类型枚举
     * @param dbDataType 数据库数据类型
     * @param dbEncode 数据库编码
     * @return 数据类型枚举
     */
    public DtInterface getDtEnumByDb(String dbDataType, String dbEncode){
        this.dtEnum = DtInterface.newInstanceByDt(dbDataType, dbEncode);
        return this.dtEnum;
    }

    /**
     * 默认建表字符串数据类型
     * @param dbEncode 数据类型编码
     * @return 字符串数据类型Sql片段
     */
    public String getStringFixedDt(String dbEncode){
        DtInterface dtEnum = DtInterface.newInstanceByView(ViewDataTypeEnum.VARCHAR.getViewFieldType(), dbEncode);
        if(dtEnum != null){
            this.setIsFixed(true);
            this.viewDataType = dtEnum.getDataType();
            this.dtEnum = dtEnum;
            DataTypeModel dataTypeModel = dtEnum.getDtLimit().convert(this);
            return dataTypeModel.getDataType() + (StringUtil.isNotEmpty(dataTypeModel.getFormatLengthStr()) ? "(" + dataTypeModel.getFormatLengthStr() + ")" : "");
        }
        return "varchar(50)";
    }

}
